package com.loong.shop.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.loong.common.domain.Pager;
import com.loong.common.executor.AsyncExecutor;
import com.loong.common.redis.RedisTools;
import com.loong.common.utils.TransformUtils;
import com.loong.global.constant.RedisKey;
import com.loong.shop.business.GoodsSkuBusiness;
import com.loong.shop.common.backend.param.GoodsSkuParam;
import com.loong.shop.common.backend.param.GoodsSkuQueryParam;
import com.loong.shop.common.backend.result.GoodsSkuResult;
import com.loong.shop.common.forehead.param.GoodsSkuForeheadParam;
import com.loong.shop.common.forehead.result.GoodsSizeDtoForeheadResult;
import com.loong.shop.common.forehead.result.GoodsSkuDtoForeheadResult;
import com.loong.shop.dto.GoodsSkuDTOResultInShop;
import com.loong.shop.mapper.GoodsSkuMapper;
import com.loong.shop.model.GoodsSku;
import com.loong.shop.model.dto.GoodsSkuDto;
import com.loong.shop.param.GoodsSkuDtoParam;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Condition;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @Description: 处理商品sku业务的handler
 * @Author: 刘群
 * @Date: 2020/10/27 8:56
 */
@Component
public class GoodsSkuHandler {

    @Resource
    private GoodsSkuBusiness skuBusiness;

    @Resource
    private GoodsSkuMapper skuMapper;
    @Resource
    private AsyncExecutor asyncExecutor;

    private void updateRedisStock(GoodsSkuParam param){
        RedisTools.valueOperations().set(RedisKey.ORDER.STOCK+param.getShopId()+"_"+param.getId(),param.getStock());
    }

    /**
     * 后台新增商品sku
     * @param param 商品sku封装的参数
     */
    public void saveGoodsSku(GoodsSkuParam param){
        param.setCreateTime(new Date());
        String jsonString = JSONArray.toJSONString(param);
        GoodsSku goodsSku = JSON.parseObject(jsonString).toJavaObject(GoodsSku.class);
        skuBusiness.save(goodsSku);
        param.setId(goodsSku.getId());
        asyncExecutor.async(()->{
            this.updateRedisStock(param);
        });

    }

    /**
     * 后台更新商品sku
     * @param param 商品sku封装的参数
     */
    public void updateGoodsSku(GoodsSkuParam param){
        param.setLastUpdateTime(new Date());
        String jsonString = JSONArray.toJSONString(param);
        GoodsSku goodsSku = JSON.parseObject(jsonString).toJavaObject(GoodsSku.class);
        skuBusiness.updateByPrimaryKeySelective(goodsSku);
        asyncExecutor.async(()->{
            this.updateRedisStock(param);
        });
    }

    /**
     * 后台批量删除商品sku
     * @param idList 商品sku的id集合
     */
    public void deleteGoodsSku(List<Long> idList){
        skuBusiness.deleteByIds(StringUtils.join(idList,","));
    }

    /**
     * 后台分页查询商品sku
     * @param param 查询参数
     * @return 分页结果
     */
    public Pager<GoodsSkuResult> pageQueryGoodsSku(GoodsSkuQueryParam param){
        Pager<GoodsSku> pager = skuBusiness.pageQuery(param, () -> skuBusiness.findGoodsSkuByParam(param));
        String jsonString = JSONArray.toJSONString(pager);
        Pager<GoodsSkuResult> resultPager = JSON.parseObject(jsonString).toJavaObject(Pager.class);
        return resultPager;
    }

    /**
     * 后台根据商品id查询商品sku
     * @param goodsId 商品id
     * @return 商品sku集合
     */
    protected List<GoodsSkuResult> findGoodsSkuById(Long goodsId){
        List<GoodsSku> goodsSkuList = skuBusiness.findGoodsSkuByGoodsId(goodsId);
        String jsonString = JSONArray.toJSONString(goodsSkuList);
        return JSON.parseArray(jsonString).toJavaList(GoodsSkuResult.class);
    }

    /**
     * 前台联合查询商品详情等信息
     * @param param 查询参数：商品id、规格组
     * @return 联合查询结果GoodsSkuDto
     */
    public GoodsSkuDtoForeheadResult joinQueryGoodsSkuDto(GoodsSkuForeheadParam param){
        //封装参数
        GoodsSkuDtoParam skuDtoParam = GoodsSkuDtoParam.builder()
                .goodsBaseId(param.getGoodsBaseId())
                .goodsSpecification(JSONArray.toJSONString(param.getGoodsSpecification()))
                .sizeValueIdList(param.getGoodsSpecification())
                .build();
        //联合查询商品详情
        GoodsSkuDto goodsSkuDto = skuMapper.joinQueryGoodsSkuDtoByParam(skuDtoParam);
       if (ObjectUtils.isEmpty(goodsSkuDto)) return null;
        List<GoodsSizeDtoForeheadResult> sizeDtoList = TransformUtils.transformList(goodsSkuDto.getSpecificationDtoList(), GoodsSizeDtoForeheadResult.class);
        return GoodsSkuDtoForeheadResult.builder()
                .goodsName(goodsSkuDto.getGoodsName())
                .goodsSkuId(goodsSkuDto.getGoodsSkuId())
                .originPrice(goodsSkuDto.getOriginPrice())
                .currentPrice(goodsSkuDto.getCurrentPrice())
                .specificationPics(goodsSkuDto.getSpecificationPics())
                .stock(goodsSkuDto.getStock())
                .sizeDtoList(sizeDtoList)
                .build();
    }

    /**
     * 根据商品规格值id查询商品sku集合
     * @param specificationSizeId 商品规格值id
     * @return 商品sku集合
     */
    protected List<GoodsSku> findGoodsSpecificationById(Long specificationSizeId){
        return skuBusiness.findGoodsSkuBySizeValueId(specificationSizeId);
    }

    /**
     * rpc接口：根据商品skuId查询商品sku
     * @param skuId 商品skuId
     * @return 商品sku结果
     */
    public GoodsSkuDTOResultInShop findGoodsSkuBySkuId(Long skuId){
        GoodsSku goodsSku = skuBusiness.findById(skuId);
        if (ObjectUtils.isEmpty(goodsSku)) return null;
        return TransformUtils.transform(goodsSku,GoodsSkuDTOResultInShop.class);
    }

    public List<GoodsSkuDTOResultInShop> findGoodsSkuListInSkuId(List<Long> skuIds) {
        Condition condition = new Condition(GoodsSku.class);
        Example.Criteria criteria = condition.createCriteria();
        if(!CollectionUtils.isEmpty(skuIds)){
            criteria.andIn("id",skuIds);
        }
        return TransformUtils.transformList(skuBusiness.findByCondition(condition),GoodsSkuDTOResultInShop.class);
    }
}
